[Terraform]Module間の値の受け渡しについて
こんにちは、コンサル部の島川です。
今回はTerraformのModule間の受け渡しについてAWSを例に説明します。コマンド一発で環境が作れるのは幸せを感じます。
Moduleのイメージ
Moduleはパーツのように扱うことができます。組み合わせ無限大です。使いたいものだけを使えばOKです。
また、Moduleで区切ることで依存関係をスッキリさせることもできます。
Module間の値のやり取り
ただし、VPCのModule書いて、EC2のModule書いて起動!と簡単にはいきません。EC2を作成する際にサブネットIDを指定する必要があり、それは一度VPCを作らないと分からないです。自動補完したいですよね。Terraformには出力された値を他のModuleで参照できる方法があります。
出力された値をOutput Valuesとして明示的に書いておくと他のModuleさんも使えるようになります。また、OutputはModuleの中に書いてあげる必要があります。
Outputの宣言例
output "instance_ip_addr" { value = aws_instance.server.private_ip }
- instance_ip_addrが変数名です。なんでもOKです。
- valueが変数に格納される値です。例ではサーバのプライベートIPを格納しています。
基本的にはこちらの宣言のみですが、他にもオプションがあります。
オプション | 概要 |
---|---|
description | 概要を書く |
sensitive | CLIへの出力を抑制する(機密情報をマスクしたいときに使用) |
depends_on | 値の出力に依存関係の指定がある場合に使用する。最後の手段といわれていて積極的に使うものではない。 |
全て書くと以下のようになります。
output "instance_ip_addr" { value = aws_instance.server.private_ip description = "The private IP address of the main server instance." sensitive = true depends_on = [ # Security group rule must be created before this IP address could # actually be used, otherwise the services will be unreachable. aws_security_group_rule.local_access, ] }
補足ですが、valueはlist形式でもOKです。
他のModuleの値を参照する
Outputに出力された値を他のModuleが参照するにはmodule.
の形式で使用します。Module NAMEが「hogeserver」でOutputの値がinstance_ip_addrならmodule.hogeserver.instance_ip_addr
のように書いてあげます。
簡単な例を用いて説明します。
例
ModuleはVPCとEC2の二つを使います。EC2作成時にVPCのModuleで作られたサブネットIDを指定したいという状況です。
今回使用するModuleはTerraform Registryのものを使用します。Terraform Registory?についてはこちら参照ください。
Terraform Registory
今回使用するTerraform Registoryです。
サンプルコード
1つのファイルにまとめてあります。
//---------- //Provider //---------- provider "aws" { region = var.aws_region } variable "aws_region" { default = "ap-northeast-1" } //---------- //variable //---------- variable ec2_name { default = "hoge-server" } //---------- //VPC Config //---------- module "vpc" { source = "../modules/VPC/terraform-aws-vpc" name = "hoge-vpc" cidr = "10.10.0.0/16" env = "test" azs = ["ap-northeast-1a", "ap-northeast-1c"] public_subnets = ["10.10.0.0/24", "10.10.1.0/24"] private_subnets = ["10.10.10.0/24", "10.10.11.0/24"] enable_nat_gateway = false single_nat_gateway = false } //---------- //EC2 config //---------- data aws_ssm_parameter amzn2_ami_latest { name = "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2" } module "hoge-server" { source = "terraform-aws-modules/ec2-instance/aws" version = "~> 2.0" name = var.ec2_name instance_count = 1 ami = data.aws_ssm_parameter.amzn2_ami_latest.value instance_type = "t3.micro" key_name = "ec2testkey" monitoring = false subnet_id = module.vpc.private_subnets[0] //private_ip = "" ebs_optimized = true root_block_device = [ { delete_on_termination = true encrypted = true iops = 60 kms_key_id = "" volume_size = 20 volume_type = "gp2" }, ] tags = { Name = var.ec2_name } }
57行目でVPC Moduleで出力された値を参照しています。今回、PublicSubnet2つとPrivateSubnet2つと複数作成しておりますので、list形式で出力されているため配列番号を指定しております。今回だとCIDR「10.10.10.0/24」のもののIDを指定している形になります。
Outputはどこで指定した?
Terraform RegistoryのModuleはOutputもきちんと書いてくれています。指定できるOutputの値もまとまってあります。
VPCだとここです。private_subnetsで指定できるのが分かります。
さいごに
TerraformのModule間のやり取りを説明しました。依存関係を分離できるので色んなModuleを組み合わせて使っていきたいですね。
Terraform Registoryめっちゃ便利じゃないですか?(これを伝えたかった)